/**
 * 上海中赢金融信息服务有限公司
 * Copyright (c) 2017-2027 Chinazyjr,Inc.All Rights Reserved.
 */

package com.sys.midware.config.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.sys.midware.config.exceptions.BConfigException;
import com.sys.midware.config.factory.AbstractConfigurationFactory;
import com.sys.midware.config.factory.PropertiesConfigurationFactory;
import com.sys.midware.config.factory.XMLConfigurationFactory;
import com.sys.midware.config.model.BNode;
import com.sys.midware.logger.Logger;
import com.sys.midware.logger.LoggerFactory;

/**
 * <b>ClassName:</b> ConfigCore.java <br/>
 * <b>Description:</b> 配置文件加载主入口 <br/>
 * <b>Date:</b> 2015年10月16日 下午3:33:20<br/>
 * 
 * @author mobing
 * @version
 */
public class ConfigCore {
    private final static Logger LOG = LoggerFactory.getLogger(ConfigCore.class);

    /**
     * 配置文件路径，可以编程式获取也可以从spring中注入进来
     */
    private String configPath;

    /**
     * 是否已经初始化
     */
    private boolean inited;

    private static ConfigCore instance = null;

    private ConfigCore() {
    }

    private ConfigCore(String configPath) {
        this.configPath = configPath;
        if (!inited) {
            init();
        }

    }

    public static ConfigCore getInstance(String configPath) {
        if (instance == null) {
            instance = new ConfigCore(configPath);
        }
        return instance;
    }

    /**
     * init 初始化
     * 
     * @param
     * @return void
     */
    public void init() {
        if (inited) {
            return;
        }
        try {
            loadConfigParams(configPath);
            inited = true;
        } catch (Exception e) {
            LOG.error("fail to load config," + e);
            throw new BConfigException("fail to load config", e);
        }
    }

    /**
     * 加载配置文件
     * 
     * @param rootConfigFile
     * @throws Exception
     */
    private void loadConfigParams(String configPath) throws Exception {
        LOG.info("begin to load root config," + configPath);
        // 解析根配置文件路径
        AbstractConfigurationFactory xcf = new XMLConfigurationFactory();
        AbstractConfigurationFactory pcf = new PropertiesConfigurationFactory();
        Configuration globalConfig = new Configuration();
        xcf.parseConfigFile(ConfigResource.getResourceAsStream(configPath), globalConfig);
        Map<String, String> confFiles = globalConfig.getConfigFiles();

        List<BNode> BNodeList = new ArrayList<BNode>();
        // 迭代跟配置文件中所有的子配置文件，并缓存
        for (Map.Entry<String, String> entry : confFiles.entrySet()) {
            LOG.info("loop load the config file：" + entry.getValue());
            String confFile = entry.getValue();
            Configuration confParam = new Configuration();
            if (confFile.endsWith(".properties")) {
                pcf.parseConfigFile(ConfigResource.getResourceAsStream(confFile), confParam);
            } else {
                xcf.parseConfigFile(ConfigResource.getResourceAsStream(confFile), confParam);
            }
            // 填充全局Map
            Map<String, Object> paramsMap = confParam.getParams();

            for (Map.Entry<String, Object> paramEntry : paramsMap.entrySet()) {
                // 设置bnodelist
                Object obj = paramEntry.getValue();
                if (obj != null && obj instanceof BNode) {
                    BNodeList.add((BNode) obj);
                }
                globalConfig.addParam(paramEntry.getKey(), paramEntry.getValue());
            }
        }
        // 设置全局
        globalConfig.setConfigFiles(confFiles);
        if (BNodeList != null && BNodeList.size() > 0) {
            globalConfig.setBNodeList(BNodeList);
        }
        
        ConfigContainer.setConfigration(globalConfig);//全局配置
        ConfigContext.setConfiguration(globalConfig);//多线程配置
        LOG.info("ConfigCore load finish for All configFile..");
    }

}
